package com.tools.genxsd.entity;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.tools.genxsd.entity.type.XsdComplexType;
import com.tools.genxsd.store.SimpleTypeStore;
import com.tools.genxsd.store.TempElementStore;
import com.tools.genxsd.util.XSDGenerateExt;
import lombok.Data;
import org.dom4j.Element;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.tools.genxsd.constant.SysConstant.CHINA_BRACKETS;

/**
 * xsd对象
 * @author: zhoubin
 * @date: 2022/11/9
 */
@Data
public class XsdDocument {

    /**
     * xsd的节点树
     */
    private XsdElement element;

    /**
     * 文档生成对象
     */
    private XSDGenerateExt generate;

    /**
     * 记录xsd类型名
     */
    private List<String> typeNameList;

    /**
     * 记录xsd类型
     */
    private List<XsdBaseType> compTypeList;

    public XsdDocument(XsdElement element, String xsdName) {
        this.generate = new XSDGenerateExt(xsdName);
        this.element = element;

        typeNameList = new ArrayList<>();
        compTypeList = new ArrayList<>();
    }

    /**
     * 生成文档对象
     * @param baseElement
     * @param element
     */
    public void elementToXsd(Element baseElement, XsdElement element) {

        generateXsdType(element);

        // 生成element
        generate.addElement(baseElement, element);

        // 如果是复杂节点
        if (Objects.nonNull(element.getXsdType())) {
            Element complexElement = generate.addComplexType(element.getXsdType());

            List<XsdElement> childList = element.getXsdType().getChildList();
            for (int i = 0; i < childList.size(); i++) {
                elementToXsd(complexElement, childList.get(i));
            }
        }

    }

    /**
     * 判断节点是否为普通节点，并创建
     * @param element
     */
    private void generateXsdType(XsdElement element) {
        if (CharSequenceUtil.isNotBlank(element.getType())) {

            if (element.getType().startsWith(CHINA_BRACKETS)) {
                XsdComplexType xsdComplexType = TempElementStore.getXsdElementType(element.getType());
                element.setType(xsdComplexType.getName());

                if (!typeNameList.contains(xsdComplexType.getName())) {
                    typeNameList.add(xsdComplexType.getName());
                    compTypeList.add(xsdComplexType);
                }

            } else {
                if (!typeNameList.contains(element.getType())) {
                    typeNameList.add(element.getType());
                    compTypeList.add(SimpleTypeStore.getTempType(element));
                }
            }
        }
    }

    /**
     * 将复杂节点添加到xsd中
     * @param complexType
     */
    public void addComplexTypeToXsd(XsdComplexType complexType) {
        Element complexElement = generate.addComplexType(complexType);

        List<XsdElement> childList = complexType.getChildList();
        for (int i = 0; i < childList.size(); i++) {
            elementToXsd(complexElement, childList.get(i));
        }
    }

    public void genXsd(String filePath) {
        elementToXsd(generate.getRoot(), element);

        while (CollUtil.isNotEmpty(compTypeList)) {
            List<XsdBaseType> baseTypeList = ObjectUtil.clone(compTypeList);
            compTypeList = new ArrayList<>();

            for (int i = 0; i < baseTypeList.size(); i++) {
                XsdBaseType baseType = baseTypeList.get(i);
                baseType.addToDocument(this);
            }
        }

        generate.writeToDisk(filePath);
    }
}
